/**
 * Cross-domain AJAX requests implementation
 * 
 * @author  Mykhailo Stadnyk <mikhus@gmail.com>
 * @package Jsl
 * @version 1.0
 */
Jsl.JsHttpRequest = Jsl.extend( Object, function() {

	/**
	 * Private members
	 */
	var
		_d      = document,
		_head   = _d.getElementsByTagName( 'head')[0] || document.body
		_script = null,
		_proxy  = new Jsl.Ajax.Proxy,

		_readyStates = { uninitialized : 0, loading : 1, loaded : 2, interactive : 3, complete : 4 };

		_onStateChange = function() {
			this.readyState = _readyStates[_script.readyState] || 0;
			if (Jsl.isFunction( this.onreadystatechange))
				this.onreadystatechange()
			;
			/**
			 * IE not always fall into 'complete' state
			 * so we just assuring that it is loaded, then just deferring
			 * onload event call
			 */
			if (this.readyState == 2) {
				_onLoad.defer( 100, this);
			}
		},

		_onLoad = function() {
			this.readyState   = _readyStates.complete;
			this.status       = 200;
			this.statusText   = 'OK';
			this.responseText = _proxy.getResponseText();
			this.responseXML  = _proxy.getResponseXml();

			var self = this;
			if (Jsl.isFunction( this.onreadystatechange)) {
				this.onreadystatechange();
				self && self.destroy();
			}
		}
	;

	/**
	 * Public properties and methods
	 */
	return {

	readyState         : 0,
	responseText       : '',
	responseXML        : null,
	status             : null,
	statusText         : '',
	onreadystatechange : Jsl.fn.empty,

	/**
	 * Class constructor
	 */
	constructor : function() {
		this.id = Jsl.id();

		_script = _d.createElement( 'script');
		_script.setAttribute( 'type', 'text/javascript');
		_script.setAttribute( 'id', this.id);

		if (Jsl.isIe)
			_script.onreadystatechange = _onStateChange.bind( this)
		; else
			_script.onload = _onLoad.bind( this)
		;

		Jsl.JsHttpRequest.$super.constructor.call( this);
	},

	/**
	 * Aborts an HTTP request
	 */
	abort : function() { if (_script) _script.src = null; },

	/**
	 * Opens a new HTTP connection via <script> element
	 * 
	 * Ignores:
	 *  - method - will be always GET
	 *  - async  - allways true
	 *
	 * "user" and "pass" will be coresponding assigned to URL's query string
	 * as "__jsl_user__" and "__jsl_pass__" params
	 * 
	 * @param {Jsl.Ajax.Proxy} proxy
	 * @param {String} url
	 * @param {Boolean} async
	 * @param {String} user
	 * @param {String} pass
	 */
	open  : function( proxy, url, async, user, pass) {
		if (proxy instanceof Jsl.Ajax.Proxy)
			_proxy = proxy
		;

		_proxy.setTargetUrl( url);

		var url = _proxy.getUrl();
		if (user) 
			url.query.set( '__jsl_user__', user)
		;
		if (pass)
			url.query.set( '__jsl_pass__', pass)
		;
		_script.src = url.toString();
	},

	/**
	 * Send a new HTTP request via <script> element
	 * 
	 * Ignores:
	 *  - body - will be always treated as null
	 */
	send : function( body) {
		_head && _head.appendChild( _script);
	},

	/**
	 * Destroys current request object and all related objects
	 */
	destroy : function() {
		_script && _head.removeChild( _script);
		_script = null;
		var self = this;
		delete self;
	},

	/**
	 * Fake methods - will do no action
	 * Only for compatibility with XMLHttpRequest interface
	 * 
	 * @return null
	 */
	setRequestHeader      : function() { return null; },
	getAllResponseHeaders : function() { return null; },
	getResponseHeader     : function( name) { return null; }

};}());
